import { filter, map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { ConfigService } from '@core/config/config.service';
import * as CryptoJS from 'crypto-js';
import { UserAuthService } from '@core/services/user-auth.service';
import { HttpService } from '@core/services/http/http.service';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http';
import { exists, missing } from '../../../utils/utils';
import { ApesMessageService } from '@shared/apes/message';
import { ApesModalService } from '@shared/apes/modal';
import { Router } from '@angular/router';

@Injectable()
export class ApiService {
  secret = '';

  constructor(private httpService: HttpService, private config: ConfigService,
              public msg: ApesMessageService, private  userAuthService: UserAuthService,
              private router: Router,
              private modalService: ApesModalService,
              private http: HttpClient) {
    this.secret = this.config.secret;
  }

  getHeaders(): HttpHeaders {
    let headers = new HttpHeaders();
    headers = headers.append('Content-Type', 'application/json;charset=UTF-8');
    return headers;
  }

  post(method: string, body: any, customHeaders?: HttpHeaders, responseType?: any): Observable<any> {
    if (exists(body) && missing(body.body)) {
      body = { 'body': JSON.stringify(body) };
    }
    const data = body || {};
    data.method = method;
    data.appKey = this.config.appKey;
    const secret = this.config.secret;
    data.version = this.config.version;
    if (method.indexOf('login') === -1) {
      data.sessionId = this.userAuthService.getToken();
    }
    data.sign = this.sign(data);
    // return this.http.post(this.config.apiURL, JSON.stringify(data), { headers:this.getHeaders()}).pipe(
    return this.httpService.post(this.config.apiURL, data, customHeaders, responseType).pipe(
      map(response => {
        if (response instanceof Blob) {
          return response;
        }
        if (response.header.code !== 'success') {
          if (response.header.code == 'invalid_session') {
            //   // this.loginService.openDialog(response, (result: any)=>{
            //   //
            //   // });

            return false;
          }
          let error = response.header.message;
          if (error.indexOf('缺少会话参数') == -1) {
            this.msg.error(error, { apesDuration: 5000 });
          } else {
            console.log('报错提示：---', error);
          }
          if (error == ' 用户信息已变更，请重新登陆！') {
            let platform = this.userAuthService.getUserInfoObj() ? this.userAuthService.getUserInfoObj().platform : '';
            this.userAuthService.removeUserInfo();
            if (platform === 'fn' || platform == 'gys') {
              this.router.navigateByUrl('/empower/login');
            } else if (platform === 'zt') {
              this.router.navigateByUrl('/headquarters/login');
            } else {
              this.router.navigateByUrl('/passport/login');
            }
          }
          return false;
        }
        return response.body;
      }));
  }

  upload(fileList: any, api ?: any): Observable<any> {
    let surl = 'fileserver/upload';
    const formData = new FormData();
    // tslint:disable-next-line:no-any
    fileList.forEach((file: any) => {
      formData.append('files', file);
    });
    if (api) {
      surl = api;
    }
    // You can use any AJAX library you like
    const req = new HttpRequest('POST', surl, formData, {
      // reportProgress: true
    });

    return this.http
      .request(req)
      .pipe(filter(e => e instanceof HttpResponse));
  }

  download(fileList: any): Observable<any> {
    const formData = new FormData();
    formData.append('body', JSON.stringify(fileList));
    const req = new HttpRequest('POST', 'fileserver/download', formData, {
      responseType: 'blob',
    });

    return this.http
      .request(req)
      .pipe(filter(e => e instanceof HttpResponse));
  }

  export(method: string, body: any): Observable<any> {
    return this.post(method, body, null, 'blob');
  }

  sign(param: object) {
    // 对参数名进行字典排序
    const arrayParam: any[] = [];
    for (const key in param) {
      arrayParam.push(key);
    }
    arrayParam.sort();
    // 拼接有序的参数名-值串
    const paramArray = [];
    paramArray.push(this.secret);
    for (let i of arrayParam) {
      paramArray.push(i + param[i]);
    }
    paramArray.push(this.secret);
    // SHA-1编码，并转换成大写，即可获得签名
    const shaSource = paramArray.join('');
    const sign = CryptoJS.SHA1(shaSource).toString(CryptoJS.enc.Hex).toUpperCase();
    return sign;
  }


  getSign(method: string, body: any): any {

    if (exists(body) && missing(body.body)) {
      body = { 'body': JSON.stringify(body) };
    }
    ;
    const data = body || {};
    data.method = method;
    data.appKey = this.config.appKey;
    data.version = this.config.version;
    return this.sign(data);
  }

  // 该函数只为解决循环依赖问题
  exists(param) {
    return exists(param);
  }
}
